package com.jumi.microservice.service.admin;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jumi.microservice.common.exception.BaseException;
import com.jumi.microservice.common.utils.DateUtil;
import com.jumi.microservice.common.utils.EnumUtil;
import com.jumi.microservice.constant.reissue.ReissueReasonEnum;
import com.jumi.microservice.constant.reissue.ReissueTypeEnum;
import com.jumi.microservice.constant.reissue.ReplacementReasonEnum;
import com.jumi.microservice.domain.ExpressDataDTO;
import com.jumi.microservice.domain.GoodsSkuMaterialDTO;
import com.jumi.microservice.dto.order.OrderInfoRequest;
import com.jumi.microservice.dto.order.OrderLogRequest;
import com.jumi.microservice.dto.admin.AdminSendRequest;
import com.jumi.microservice.dto.admin.UpdateLogisticsNoRequest;
import com.jumi.microservice.dto.afterseal.AfterSaleGoodsInfo;
import com.jumi.microservice.dto.reponse.JmUserReponse;
import com.jumi.microservice.entity.AfterSealOrder;
import com.jumi.microservice.entity.AfterSealOrderGoods;
import com.jumi.microservice.enumerate.LogisticsStatusEnum;
import com.jumi.microservice.enumerate.OrderStatusEnum;
import com.jumi.microservice.enumerate.SelfFlagEnum;
import com.jumi.microservice.mapper.AfterSealOrderGoodsMapper;
import com.jumi.microservice.mapper.AfterSealOrderMapper;
import com.jumi.microservice.service.*;
import com.jumi.microservice.warehouseout.api.ApiChangeShippingCodeService;
import com.jumi.microservice.warehouseout.vo.JmSaledOrderWarehouseOutVo;
import com.jumi.microservice.warehouseout.vo.ShipingCodeDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author by mazhao
 * @Classname AdminSendService
 * @Description TODO
 * @Date 2020/9/25 9:43
 */
@Service
@RefreshScope
public class AdminSendService {

    private static final Logger log = LoggerFactory.getLogger(AdminSendService.class);

    @Resource
    AfterSealOrderMapper afterSealOrderMapper;
    @Resource
    AfterSealOrderGoodsMapper afterSealOrderGoodsMapper;
    @DubboReference
    private IOrderDubboService iOrderDubboService;
    @DubboReference
    private IOrderService iOrderService;
    @DubboReference
    BasicDataService basicDataService;
//    @DubboReference
//    ApiSaledOrderWarehouseOutService iSaledMaterialService;
    @DubboReference
    IMemberService iUserService;
    @DubboReference
    BasicDataApi iExpressService;
    @DubboReference
    ApiChangeShippingCodeService iSaledChangeLogisticsNoService;
    @Resource
    ProducerBean producerBean;

    /**
     * 导入数据错误
     */
    public  static List<String> importError = new ArrayList<>();


    /**
     * 单个 编辑发货
     * @param request
     * @param uid
     * @param name
     * @return
     */
    public boolean send(AdminSendRequest request,Long uid,String name){
        QueryWrapper<AfterSealOrder> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("id",request.getOrderId()).eq("order_status",OrderStatusEnum.READY_TO_SHIP.getCode());
        AfterSealOrder afterSealOrder = afterSealOrderMapper.selectOne(queryWrapper1);
        log.info("从afterOrder编辑发货 [{}]", JSON.toJSONString(afterSealOrder));
        if(afterSealOrder==null){
            throw new BaseException(500,"该订单未处于待发货状态！");
        }
        afterSealOrder.setRealLogisticsNo(request.getRealLogisticsNo());
        afterSealOrder.setExpressCode(request.getExpressCompany());
        afterSealOrder.setOrderStatus(OrderStatusEnum.READY_TO_RECEIVE.getCode());
        if(request.getRemark()!=null && !request.getRemark().trim().isEmpty()){
            afterSealOrder.setRemark(request.getRemark());
        }
        afterSealOrder.setConfirmTime(DateUtil.getDateAfterDay(new Date(),8));
        List<AfterSealOrder> orderList = new ArrayList<>();
        orderList.add(afterSealOrder);
        //修改订单状态
        afterSealOrderMapper.updateById(afterSealOrder);
        QueryWrapper<AfterSealOrderGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag",0).eq("order_id",afterSealOrder.getId());
        List<AfterSealOrderGoods> goodsList = afterSealOrderGoodsMapper.selectList(queryWrapper);
        //修改商品状态
        for(AfterSealOrderGoods afterSealOrderGoods:goodsList){
            afterSealOrderGoods.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            afterSealOrderGoods.setRemark(request.getRemark()==null?"":request.getRemark());
            afterSealOrderGoodsMapper.updateById(afterSealOrderGoods);
        }
        //通知物料出库
        log.info("---------从afterOrder编辑发货-------[通知物料出库]---- [{}][{}]", JSON.toJSONString(orderList),name);
        batchNoticeMaterial(orderList,name);
        //添加日志
        addLog(uid,name,request.getOrderNo(),"编辑发货操作");
        return true;
    }

    /**
     * 插入日志记录表
     * @param uid
     * @param name
     * @param orderNo
     * @param log
     */
    public Boolean addLog(Long uid,String name,String orderNo,String log){
        OrderLogRequest orderLogRequest =  new OrderLogRequest();
        orderLogRequest.setUserFlag((byte)2);
        orderLogRequest.setOrderSn(orderNo);
        orderLogRequest.setOperatorName(name);
        orderLogRequest.setOperatorId(uid);
        orderLogRequest.setLog(log);
        return iOrderDubboService.addOrderLog(orderLogRequest);
    }

    /**
     * 待发货导入处理方法
     * @param list
     * @param uid
     * @param name
     */
    public void ExcelImportHandler(List<AfterSaleGoodsInfo> list ,Long uid,String name){
        importError.clear();
        if(list.isEmpty()){
            return ;
        }
        List<AfterSealOrder> orderList = new ArrayList<>();
        Map<String,String> expressMap = availableExpressInfo();
        for(AfterSaleGoodsInfo afterSaleGoodsInfo:list){
            if(afterSaleGoodsInfo.getRealLogisticsNo()==null && afterSaleGoodsInfo.getExpressCompany()==null){
                continue;
            }
            if(afterSaleGoodsInfo.getRealLogisticsNo()==null || afterSaleGoodsInfo.getExpressCompany()==null){
                importError.add(afterSaleGoodsInfo.getOrderNo());
                continue;
            }
            if(afterSaleGoodsInfo.getGoodsAmount()<=0 || !expressMap.containsKey(afterSaleGoodsInfo.getExpressCompany())){
                importError.add(afterSaleGoodsInfo.getOrderNo());
                continue;
            }
            if(!importError.isEmpty()){
                continue;
            }
            AfterSealOrder afterSealOrder = new AfterSealOrder();
            afterSealOrder.setId(afterSaleGoodsInfo.getOrderId());
            afterSealOrder.setRealLogisticsNo(afterSaleGoodsInfo.getRealLogisticsNo());
            if(expressMap.containsKey(afterSaleGoodsInfo.getExpressCompany())){
                afterSealOrder.setExpressCode(expressMap.get(afterSaleGoodsInfo.getExpressCompany()));
            }
            afterSealOrder.setBuyerId(afterSaleGoodsInfo.getBuyerId());
            afterSealOrder.setRemark(afterSaleGoodsInfo.getRemark()==null?"":afterSaleGoodsInfo.getRemark());
            orderList.add(afterSealOrder);
            addLog(uid,name,afterSaleGoodsInfo.getOrderNo(),"excel批量导入发货操作");
        }
        if(!orderList.isEmpty()){
            afterSealOrderMapper.batchUpdateAfterOrder(orderList);
            afterSealOrderGoodsMapper.updateGoodsStatus(orderList);
            batchNoticeMaterial(orderList,name);
        }
    }

    /**
     * 修改售后订单状态及物流状态
     * @param orders
     * @return
     */
    public boolean updateAfterOrderStatus(List<AfterSealOrder> orders){
        if(orders.isEmpty()){
            return true;
        }
        Map<String,String> expressMap = allExpressInfo();
        for(AfterSealOrder afterSealOrder:orders){
            if(expressMap.containsKey(afterSealOrder.getRemark())){
                afterSealOrder.setExpressCode(expressMap.get(afterSealOrder.getRemark()));
            }
        }
        return afterSealOrderMapper.batchUpdateAfterOrderByOrderNo(orders) >0;
    }

//    /**
//     * 修改售后订单商品状态
//     * @param orders
//     * @return
//     */
//    public boolean updateAfterOrderGoodsStatus(List<AfterSealOrder> orders){
//        if(orders.isEmpty()){
//            return true;
//        }
//        UpdateWrapper<AfterSealOrderGoods> updateWrapper = new UpdateWrapper<>();
//        updateWrapper.eq("goods_status",LogisticsStatusEnum.WAIT_SEND.getCode()).eq("del_flag",0)
//                .in("order_id",orders.stream().map(AfterSealOrder::getId).collect(Collectors.toList()));
//        AfterSealOrderGoods afterSealOrderGoods = new AfterSealOrderGoods();
//        afterSealOrderGoods.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
//        return afterSealOrderGoodsMapper.update(afterSealOrderGoods,updateWrapper) > 0;
//    }

    /**
     * 订单编号修改商品状态
     * @param orders
     * @return
     */
    public boolean updateAfterOrderGoodsStatusByOrderNo(List<AfterSealOrder> orders){
        if(orders.isEmpty()){
            return true;
        }
        QueryWrapper<AfterSealOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("order_no",orders.stream().map(AfterSealOrder::getOrderNo).collect(Collectors.toList()));
        List<Integer> ids = afterSealOrderMapper.selectList(queryWrapper).stream().map(AfterSealOrder::getId).collect(Collectors.toList());
        UpdateWrapper<AfterSealOrderGoods> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("goods_status",LogisticsStatusEnum.WAIT_SEND.getCode()).eq("del_flag",0)
                .in("order_id",ids);
        AfterSealOrderGoods afterSealOrderGoods = new AfterSealOrderGoods();
        afterSealOrderGoods.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
        return afterSealOrderGoodsMapper.update(afterSealOrderGoods,updateWrapper) > 0;
    }

    /**
     * 订单 通知物料出库
     * @param orderList
     */
    public void batchNoticeMaterial(List<AfterSealOrder> orderList,String name){
        if(orderList.isEmpty()){
            return;
        }
        List<Integer> ids = new ArrayList<>();
        if(orderList.get(0).getId()==null && orderList.get(0).getOrderNo()!=null){
            QueryWrapper<AfterSealOrder> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.in("order_no",orderList.stream().map(AfterSealOrder::getOrderNo).collect(Collectors.toList()));
            ids = afterSealOrderMapper.selectList(queryWrapper1).stream().map(AfterSealOrder::getId).collect(Collectors.toList());
            //查询出所有的orderId
            if(ids.isEmpty()){
                return;
            }
        }
        //查询出所有商品
        QueryWrapper<AfterSealOrderGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag",0).eq("self_flag",SelfFlagEnum.YES_SELF.getCode());
        if(!ids.isEmpty()){
            queryWrapper.in("order_id",ids);
        }else{
            queryWrapper.in("order_id",orderList.stream().map(AfterSealOrder::getId).collect(Collectors.toList()));
        }
        List<AfterSealOrderGoods> goodsList = afterSealOrderGoodsMapper.selectList(queryWrapper);
        if(goodsList.isEmpty()){
            return;
        }
        //获取物料信息
        Map<Integer,GoodsSkuMaterialDTO> materialDTOMap = getMaterialMap(goodsList);
        //获取订单信息
        Map<Integer,AfterSealOrder> orderInfoMap = getOrderInfo(orderList);
        //获取买家信息
        Map<Long,JmUserReponse> buyerMap = getJmUserMap(orderInfoMap.values().stream().collect(Collectors.toList()));
//        List<JmSaledOrderWarehouseOutVo> list = new ArrayList<>();
        for(AfterSealOrderGoods afterSealOrderGoods:goodsList){
            AfterSealOrder afterSealOrder = null;
            JmUserReponse jmUserReponse = null;
            GoodsSkuMaterialDTO goodsSkuMaterialDTO = null;
            JmSaledOrderWarehouseOutVo jmSaledOrderWarehouseOutVo = new JmSaledOrderWarehouseOutVo();
            if(materialDTOMap.containsKey(afterSealOrderGoods.getGoodsId())){
                goodsSkuMaterialDTO = materialDTOMap.get(afterSealOrderGoods.getGoodsId());
            }
            if(orderInfoMap.containsKey(afterSealOrderGoods.getOrderId())){
                afterSealOrder = orderInfoMap.get(afterSealOrderGoods.getOrderId());
                if(buyerMap.containsKey(afterSealOrder.getBuyerId())){
                    jmUserReponse = buyerMap.get(afterSealOrder.getBuyerId());
                }
            }
            jmSaledOrderWarehouseOutVo.setX(afterSealOrderGoods.getGoodsAmount());
            jmSaledOrderWarehouseOutVo.setSaledOrderCode(afterSealOrder!=null?afterSealOrder.getReissueNo():"");
            ReissueTypeEnum reissueTypeEnum = EnumUtil.getByCode(afterSealOrder.getOrderType().intValue(),ReissueTypeEnum.class);
            jmSaledOrderWarehouseOutVo.setSaledType(reissueTypeEnum!=null?reissueTypeEnum.getDesc():"");
            jmSaledOrderWarehouseOutVo.setSaledTypeId(afterSealOrder.getOrderType());
            jmSaledOrderWarehouseOutVo.setNewOrderCode(afterSealOrder.getOrderNo());
            jmSaledOrderWarehouseOutVo.setSendWarehouseId(afterSealOrderGoods.getWarehouse());
            if(jmUserReponse==null){
                jmSaledOrderWarehouseOutVo.setBuyerMessage("");
            }else{
                jmSaledOrderWarehouseOutVo.setBuyerMessage(jmUserReponse.getName()+" "+jmUserReponse.getMobile());
            }
            jmSaledOrderWarehouseOutVo.setBuyerDetail(afterSealOrder.getReceiverName()
                    +afterSealOrder.getReceiverPhone()+" "+afterSealOrder.getReceiverAddress());
            jmSaledOrderWarehouseOutVo.setSendWarehouseId(afterSealOrderGoods.getWarehouse());
            if(afterSealOrder.getReissueNo().startsWith("HH")){
                ReplacementReasonEnum replacementReasonEnum = EnumUtil.getByCode(afterSealOrder.getReissueReason().intValue(),ReplacementReasonEnum.class);
                jmSaledOrderWarehouseOutVo.setSaledReason(replacementReasonEnum!=null?replacementReasonEnum.getDesc():"");
            }else{
                ReissueReasonEnum reissueReasonEnum = EnumUtil.getByCode(afterSealOrder.getReissueReason().intValue(), ReissueReasonEnum.class);
                jmSaledOrderWarehouseOutVo.setSaledReason(reissueReasonEnum!=null?reissueReasonEnum.getDesc():"");
            }
            jmSaledOrderWarehouseOutVo.setShippingCode(afterSealOrder.getRealLogisticsNo());
            jmSaledOrderWarehouseOutVo.setSelledRemark(afterSealOrder.getReissueRemark());
            jmSaledOrderWarehouseOutVo.setOprator(afterSealOrder.getPromoterName());
            jmSaledOrderWarehouseOutVo.setMaterialSkuRelationshipDTOList(goodsSkuMaterialDTO!=null?
                    goodsSkuMaterialDTO.getMaterialSkuRelationship():new ArrayList<>());
            jmSaledOrderWarehouseOutVo.setOprator(name);
//            list.add(jmSaledOrderWarehouseOutVo);
            try {
                Message sendMessage = new Message("afterOrderOut", "", "", JSON.toJSONBytes(jmSaledOrderWarehouseOutVo));
                producerBean.send(sendMessage);
                log.info("发送售后订单物料出库队列成功 [{}]",JSON.toJSONString(jmSaledOrderWarehouseOutVo));
            } catch (Exception e) {
                log.info("发送售后订单物料出库队列失败 [{}]",e.getMessage());
            }
        }
//        if(!list.isEmpty()){
//            iSaledMaterialService.add(list);
//        }
    }

    /**
     * 获取买家信息
     * @param orderList
     * @return
     */
    public Map<Long,JmUserReponse> getJmUserMap(List<AfterSealOrder> orderList){
        //获取买家信息
        List<JmUserReponse> jmUserResponseList = iUserService.getMemberByUids(orderList.stream().map(a->a.getBuyerId().intValue()).collect(Collectors.toList())).getData();
        Map<Long,JmUserReponse> map = new HashMap<>(jmUserResponseList.size());
        for(JmUserReponse jmUserReponse:jmUserResponseList){
            map.put(jmUserReponse.getId().longValue(),jmUserReponse);
        }
        return map;
    }

    /**
     * 获取订单信息
     * @param orderIds
     * @return
     */
    public Map<Integer,AfterSealOrder> getOrderInfo(List<AfterSealOrder> orderIds){
        if(orderIds.isEmpty()){
            return null;
        }
        QueryWrapper<AfterSealOrder> queryWrapper = new QueryWrapper<>();
        if(orderIds.get(0).getId()==null){
            queryWrapper.in("order_no",orderIds.stream().map(AfterSealOrder::getOrderNo).collect(Collectors.toList()));
        }else{
            queryWrapper.in("id",orderIds.stream().map(AfterSealOrder::getId).collect(Collectors.toList()));
        }
        List<AfterSealOrder> list = afterSealOrderMapper.selectList(queryWrapper);
        Map<Integer,AfterSealOrder> map = new HashMap<>(list.size());
        for(AfterSealOrder afterSealOrder:list){
            map.put(afterSealOrder.getId(),afterSealOrder);
        }
        return map;
    }


    /**
     * 获取物料信息
     * @param goodsList
     * @return
     */
    public Map<Integer,GoodsSkuMaterialDTO> getMaterialMap(List<AfterSealOrderGoods> goodsList){
        //请求接口获取物料信息
        List<GoodsSkuMaterialDTO> materialDTOS =  basicDataService.getMaterialSkuRelationshipByIds(goodsList.stream()
                .map(a->a.getGoodsId().longValue()).collect(Collectors.toList()));
        Map<Integer,GoodsSkuMaterialDTO> map = new HashMap<>(materialDTOS.size());
        for(GoodsSkuMaterialDTO goodsSkuMaterialDTO:materialDTOS){
            map.put(goodsSkuMaterialDTO.getSkuId().intValue(),goodsSkuMaterialDTO);
        }
        return map;
    }

    /**
     * 修改真实物流单号
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLogisticsNo(UpdateLogisticsNoRequest request,Long uid,String name){
        QueryWrapper<AfterSealOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no",request.getOrderNo());
        AfterSealOrder afterSealOrder = afterSealOrderMapper.selectOne(queryWrapper);
        String oldRealLogisticsNo = afterSealOrder.getRealLogisticsNo();
        if(afterSealOrder==null){
            return true;
        }
        afterSealOrder.setRealLogisticsNo(request.getRealLogisticsNo());
        afterSealOrder.setExpressCode(request.getExpressCompany());
        afterSealOrderMapper.updateById(afterSealOrder);
        //请求物料修改接口
        ShipingCodeDto shipingCodeDto = new ShipingCodeDto();
        shipingCodeDto.setType(2);
        shipingCodeDto.setNewShippingCode(request.getRealLogisticsNo());
        shipingCodeDto.setOldShippingCode(oldRealLogisticsNo);
        shipingCodeDto.setUserId(uid.toString());
        shipingCodeDto.setUserName(name);
        shipingCodeDto.setOrderCode(afterSealOrder.getOrderNo());
        iSaledChangeLogisticsNoService.changeShippingCodeService(shipingCodeDto);
        //添加日志
        OrderLogRequest orderLogRequest =  new OrderLogRequest();
        orderLogRequest.setUserFlag((byte)2);
        orderLogRequest.setOrderSn(request.getOrderNo());
        orderLogRequest.setOperatorName(name);
        orderLogRequest.setOperatorId(uid);
        orderLogRequest.setLog("修改物流单号操作 原运单号："+oldRealLogisticsNo+"，新运单号："+request.getRealLogisticsNo());
        iOrderDubboService.addOrderLog(orderLogRequest);
        return true;
    }


    /**
     * 获取快递公司信息
     * @return
     */
    public Map<String,String> availableExpressInfo(){
        List<ExpressDataDTO> res = iExpressService.selectExpressList();
        return res.stream().filter(e->e.getExpressCode()!=null && e.getStatus()==1&&e.getIsDel()==0)
                .collect(Collectors.toMap(ExpressDataDTO::getExpressName,ExpressDataDTO::getExpressCode));
    }

    public Map<String,String> allExpressInfo(){
        List<ExpressDataDTO> res = iExpressService.selectExpressList();
        return res.stream().filter(e->e.getExpressCode()!=null)
                .collect(Collectors.toMap(ExpressDataDTO::getExpressName,ExpressDataDTO::getExpressCode));
    }

    /**
     * 售后订单自动确认收货
     */
    @Scheduled(fixedDelay = 30 * 60 * 1000)
    @Transactional(rollbackFor = Exception.class)
    public void autoConfirmOrder(){
        QueryWrapper<AfterSealOrder> userOrderQueryWrapper = new QueryWrapper<>();
        userOrderQueryWrapper.eq("order_status", OrderStatusEnum.READY_TO_RECEIVE.getCode())
                .isNotNull("confirm_time").le("confirm_time", new Date());
        List<AfterSealOrder> list = afterSealOrderMapper.selectList(userOrderQueryWrapper);
        if(list.isEmpty()){
            return ;
        }
        AfterSealOrder afterSealOrder = new AfterSealOrder();
        afterSealOrder.setOrderStatus(OrderStatusEnum.COMPLETED.getCode());
        afterSealOrder.setConfirmTime(new Date());
        int r = afterSealOrderMapper.update(afterSealOrder,userOrderQueryWrapper);
        if(r>0){
            UpdateWrapper<AfterSealOrderGoods> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("order_id",list.stream().map(AfterSealOrder::getId).collect(Collectors.toList()));
            AfterSealOrderGoods afterSealOrderGoods = new AfterSealOrderGoods();
            afterSealOrderGoods.setGoodsStatus(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode());
            r = afterSealOrderGoodsMapper.update(afterSealOrderGoods,updateWrapper);
            if(r>0){
                for(AfterSealOrder afterSealOrder1:list){
                    addLog(0L,"系统",afterSealOrder1.getOrderNo(),"系统自动确认收货");
                    addLog(0L,"系统",afterSealOrder1.getOriginalOrderNo(),
                            "售后订单"+afterSealOrder1.getOrderNo()+"系统自动确认收货");
                }
            }
        }
    }

}
